package com.akcome.apollo.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.common.utils.bean.AkResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.akcome.apollo.common.AkResultHelper;
import com.akcome.apollo.common.ApolloConstants;
import com.akcome.apollo.common.AuthUtils;
import com.akcome.apollo.common.TokenHelper;
import com.akcome.apollo.domain.BmpAccount;
import com.akcome.apollo.domain.BmpAccountWallet;
import com.akcome.apollo.domain.enums.MsgTemplateEnum;
import com.akcome.apollo.domain.enums.YesOrNoEnum;
import com.akcome.apollo.domain.resultcode.CommonResultCode;
import com.akcome.apollo.domain.resultcode.UserResultCode;
import com.akcome.apollo.repository.BmpAccountWalletRepository;
import com.akcome.apollo.service.BmpAccountService;
import com.akcome.apollo.service.BmpAccountWalletService;
import com.akcome.apollo.service.MailService;
import com.alibaba.fastjson.JSON;


/**
 * 账户钱包Service接口实现
 *
 * @author wn
 * @version $v: 1.0.0, $time:2017-12-26 08:49:00 Exp $
 */
@Service
public class BmpAccountWalletServiceImpl implements BmpAccountWalletService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private BmpAccountWalletRepository bmpAccountWalletRepository;
	
	@Autowired
	private BmpAccountService bmpAccountService;
	
	@Autowired
	private AkResultHelper akResultHelper;
	
	@Autowired
	private TokenHelper tokenHelper;
	
	@Autowired
	private MailService mailService;
	
	@Value("${systemUrl}")
	private String systemUrl;
	
	@Override
	public BmpAccountWallet save(BmpAccountWallet bmpAccountWallet){
		return bmpAccountWalletRepository.save(bmpAccountWallet);
	}
	
	@Override
	public BmpAccountWallet findOne(Long id){
		return bmpAccountWalletRepository.findOne(id);
	}
	
	@Override
	public int countByAccountIdEnable(Long accountId){
		return bmpAccountWalletRepository.countByAccountIdAndIsEnable(accountId, YesOrNoEnum.YES.getCode());
	}
	
	@Override
	public int countByAccountIdAndCoinType(Long accountId,String coinType){
		return bmpAccountWalletRepository.countByAccountIdAndCoinType(accountId, coinType);
	}
	
	@Override
	public AkResult addwalletAddr(BmpAccountWallet bmpAccountWallet){
		
		//发送验证邮件
		String email = AuthUtils.getUserName();
		try {
			String walletAddr = bmpAccountWallet.getWalletAddr();
			if(StringUtils.isBlank(walletAddr)){
				return akResultHelper.buildFailAkResult(CommonResultCode.PARAM_MISS); 
			}
			if(walletAddr.length()!=ApolloConstants.WALLET_ADDR_LENGTH){
				return akResultHelper.buildFailAkResult(UserResultCode.WALLET_ADDR_FORMAT_ERROR); 
			}
			Long accountId = bmpAccountWallet.getAccountId();
			String coinType = bmpAccountWallet.getCoinType();
			Long id = bmpAccountWallet.getId();
			if(null!=id){
				//修改
				BmpAccountWallet oldAccountWallet =findOne(id);
				if(!oldAccountWallet.getCoinType().equals(coinType)){
					int acCount = countByAccountIdAndCoinType(accountId, coinType);
					if(acCount>0){
						return akResultHelper.buildFailAkResult(UserResultCode.UK_ACCOUNT_COINTYPE); 
					}
				}
			}else{
				int acCount = countByAccountIdAndCoinType(accountId, coinType);
				if(acCount>0){
					return akResultHelper.buildFailAkResult(UserResultCode.UK_ACCOUNT_COINTYPE); 
				}
			}
			
			Map<String, Object> model = new HashMap<>();
			model.put("email", email);
			String token = tokenHelper.generateToken(JSON.toJSONString(bmpAccountWallet));
			model.put("url", systemUrl+"validate/addwalletAddr?token="+token);
			mailService.mailSender(email, MsgTemplateEnum.MAIL_WALLET_VALIDATE, model,LocaleContextHolder.getLocale());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("添加修改钱包地址异常",e);
			return akResultHelper.buildFailAkResult(CommonResultCode.SYSTEM_ERROR);
		}
		
		return akResultHelper.buildSuccessAkResult(email);
	}
	
	@Override
	public void submitWalletAddr(BmpAccountWallet bmpAccountWallet){
		Long accountId = bmpAccountWallet.getAccountId();
		
		String coinType = bmpAccountWallet.getCoinType();
		
		Date now = new Date();
		Long id = bmpAccountWallet.getId();
		if(null!=id){
			//修改
			boolean pass = true;
			BmpAccountWallet oldAccountWallet =findOne(id);
			if(!oldAccountWallet.getCoinType().equals(coinType)){
				int acCount = countByAccountIdAndCoinType(accountId, coinType);
				if(acCount>0){
					pass = false;
				}
			}
			if(pass){
				oldAccountWallet.setAccountId(accountId);
				oldAccountWallet.setCoinType(coinType);
				oldAccountWallet.setPayMode(bmpAccountWallet.getPayMode());
				oldAccountWallet.setWalletAddr(bmpAccountWallet.getWalletAddr());
				oldAccountWallet.setUpdateTime(now);
				oldAccountWallet = save(oldAccountWallet);
				//如果修改的地址是当前正在挖矿的币种则同步修改账户信息
				if(YesOrNoEnum.YES.getCode().equals(oldAccountWallet.getIsEnable())){
					BmpAccount bmpAccount = bmpAccountService.findOne(accountId);
					bmpAccount.setCoinType(oldAccountWallet.getCoinType());
					bmpAccount.setPayMode(oldAccountWallet.getPayMode());
					bmpAccount.setUpdateTime(now);
					bmpAccountService.save(bmpAccount);
				}
			}
		}else{
			int acCount = countByAccountIdAndCoinType(accountId, coinType);
			if(acCount==0){
				BmpAccount bmpAccount = bmpAccountService.findOne(accountId);
				if(bmpAccount.getCoinType().equals(bmpAccountWallet.getCoinType())){
					bmpAccount.setPayMode(bmpAccountWallet.getPayMode());
					bmpAccount.setUpdateTime(now);
					bmpAccountService.save(bmpAccount);
				}
				//新增
				bmpAccountWallet.setCreateTime(now);
				bmpAccountWallet.setUpdateTime(now);
				save(bmpAccountWallet);
			}
		}
	}
	
	@Override
	public List<BmpAccountWallet> findByAccountId(Long accountId){
		return bmpAccountWalletRepository.findByAccountId(accountId);
	}
	
	@Override
	public AkResult delete(Long walletId){
		int count =bmpAccountWalletRepository.countByIdAndUserId(walletId, AuthUtils.getUserId());
		if(count==0){
			return akResultHelper.buildFailAkResult(CommonResultCode.PARAM_ERROR);
		}
		bmpAccountWalletRepository.delete(walletId);
		return akResultHelper.buildSuccessAkResult(null);
	}
	
	@Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false, rollbackFor = Exception.class)
	public AkResult editCoin(Long walletId,Long accountId){
		try {
			BmpAccountWallet accountWallet = findOne(walletId);
			if(!accountWallet.getAccountId().equals(accountId)){
				return akResultHelper.buildFailAkResult(CommonResultCode.PARAM_ERROR);
			}
			
			BmpAccount bmpAccount = bmpAccountService.findOne(accountId);
			bmpAccount.setCoinType(accountWallet.getCoinType());
			bmpAccount.setPayMode(accountWallet.getPayMode());
			bmpAccount.setUpdateTime(new Date());
			bmpAccountService.save(bmpAccount);
			accountWallet.setIsEnable(YesOrNoEnum.YES.getCode());
			save(accountWallet);
			//修改其他地址为禁用
			disableWallet(walletId, accountId);
			return akResultHelper.buildSuccessAkResult(null);
		} catch (Exception e) {
			e.printStackTrace();
			return akResultHelper.buildFailAkResult(CommonResultCode.SYSTEM_ERROR);
			
		}
	}
	
	@Override
	public int disableWallet(Long id ,Long accountId){
		return bmpAccountWalletRepository.disableWallet(id, accountId);
	}
}
